-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Additional improvements to Store and Record API #1082
Conversation
lbwexler
commented
Apr 19, 2019
- Restore 'raw' data property on record.
- More maintainable handling of name collision
- Don't require user to delete bad 'id' property on raw data. idSpec always wins.
- Cleanup to left/right chooser
+ Restore 'raw' data property on record. + More maintainable handling of name collision + Don't require user to delete bad 'id' property on raw data. idSpec always wins. + Cleanup to left/right chooser
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like some good cleanups / hardening of this part of our system.
I am still somewhat mystified as to how raw will be used, but if it's helpful it also seems very natural.
@@ -43,20 +42,31 @@ export class Record { | |||
* requiring children to also be recreated.) | |||
* | |||
* @param {Object} c - Record configuration | |||
* @param {Object} c.data - data for constructing the record. | |||
* @param {Object} c.raw - raw data for record. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know that apps aren't expected to construct records, but this is still a bit confusing here. How about:
c.data - data used to construct this record, pre-processed if applicable by store.processRawData().
c.raw - the same data, prior to any store pre-processing.
Would that be incrementally more clear?
data/Record.js
Outdated
@@ -43,20 +42,31 @@ export class Record { | |||
* requiring children to also be recreated.) | |||
* | |||
* @param {Object} c - Record configuration | |||
* @param {Object} c.data - data for constructing the record. | |||
* @param {Object} c.raw - raw data for record. | |||
* @param {BaseStore} c.store - store containing this record. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Realizing that LocalStore defines idSpec
, which means that's what you need to be passing in here. Yet BaseStore
also declares interfaces that deal in Records/RecordSets.
We've discussed how we might want to unwind BaseStore, taking LocalStore -> Store and having it be the primary/parent store class. I dunno if we want to deal with that now.
Alternatively we could move idSpec to BaseStore, or adjust the docs here to punt a bit and deal with LocalStore only.
|
||
this.id = id; | ||
this.store = store; | ||
this.raw = raw; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should add an @member
declaration
if (name == 'id') return; | ||
throwIf( | ||
name in this, | ||
`Field name "${name}" cannot be used for data. It is reserved as a top-level property of the Record class.` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great that this check moved into this class.
let data = raw; | ||
if (store.processRawData) { | ||
data = store.processRawData(raw); | ||
throwIf(!data, 'processRawData should return an object. If writing/editing, be sure to return a clone!'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we enforce processRawData always returning a new object? Is there a likely/important use case where we have processRawData making decisions to not edit some objects (and it would be terribly inefficient to force it to clone anyway)?
|
||
const rawRec = this._data.find(raw => raw === rec.raw); | ||
rawRec.side = (rec.side === 'left' ? 'right' : 'left'); | ||
rec.raw.side = (rec.side === 'left' ? 'right' : 'left'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll be honest - I am not gonna dive into LRChooser code right now, but this seems very weird to be modifying the raw object.
@haynesjm42 - Lee and I just talked this over a bunch more and he is going to press forward with some additional refactoring. Looking to collapse BaseStore+LocalStore -> Store + provide an efficient children getter on record (not directly related to this raw data change but will roll it all up into a bigger data package redo). |
+ id should not be a field + LocalStore -> Store + Remove BaseStore
+ Implement record.children, record.allChildren + lint
This should be good to review and merge. Thanks to everyone for getting this in a good place. I think we now have a very tight, efficient TreeStore, with a very usable API. |
+ add rootRecords/allRootRecords getters
made a few tiny improvements -- john, can you take one more look ?
…On Mon, Apr 22, 2019 at 11:29 AM John Haynes ***@***.***> wrote:
***@***.**** approved this pull request.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#1082 (review)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AARTL2MVFTI35WKE2T4SK63PRXKTXANCNFSM4HHBKLFQ>
.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, just a couple minor comments.
Also it occurred to me that we have some logic in Grid which handles determining if the date is hierarchical or not, I wonder if we should move that into Store as a getter?
data/impl/RecordSet.js
Outdated
records.forEach(r => { | ||
const {parentId} = r; | ||
if (parentId) { | ||
let children = ret.get(parentId); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like this could be const
?
desktop/cmp/store/StoreCountLabel.js
Outdated
@@ -58,7 +57,7 @@ export class StoreCountLabel extends Component { | |||
if (!store) return null; | |||
|
|||
const includeChildren = withDefault(this.props.includeChildren, false), | |||
count = includeChildren ? store.count : this.rootCount(store), | |||
count = includeChildren ? store.count : store.rootRecords.length, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we've gone back and forth with this a few times, but should we have rootCount
on Store for symmetry between the records
and rootRecords
properties? (I'm fine either way, we can always add it later if we see apps or other components with this kind of code)
+ Add efficient bulk remove functionality, streamline remove implementation
*/ | ||
@action | ||
removeRecord(id) { | ||
this._all = this._all.removeRecord(id); | ||
removeRecords(ids) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could do a ids = castArray(ids)'
here just to make it nice and clean for apps to remove a single record (something I tend to do a lot in inline editable grids)
Great - excellent to see this landed! 🚀 |